11 bool operator < (const Point
&p
) const {
12 return (x
< p
.x
|| (x
== p
.x
&&y
< p
.y
));
17 // Return a positive value, if OAB makes a counter-clockwise turn,
18 // negative for clockwise turn, and zero if the points are collinear.
19 long long cross(const Point
&O
, const Point
&A
, const Point
&B
)
21 return (A
.x
- O
.x
) * (B
.y
- O
.y
) - (A
.y
- O
.y
) * (B
.x
- O
.x
);
24 // Returns a list of points on the convex hull in counter-clockwise order.
25 // Note: the last point in the returned list is the same as the first one.
26 vector
<Point
> convexHull(vector
<Point
> P
)
28 long long n
= P
.size(), k
= 0;
31 // Sort Points lexicographically
32 sort(P
.begin(), P
.end());
35 for (long long i
= 0; i
< n
; i
++) {
36 while (k
>= 2 && cross(H
[k
-2], H
[k
-1], P
[i
]) < 0) k
--;
41 for (long long i
= n
-2, t
= k
+1; i
>= 0; i
--) {
42 while (k
>= t
&& cross(H
[k
-2], H
[k
-1], P
[i
]) < 0) k
--;
50 void printPnt(const Point
&p
){
51 cout
<< "(" << p
.x
<< "," << p
.y
<< ")";
59 long long ilen
, nails
;
61 vector
<Point
> g(nails
);
63 for (long long i
=0; i
<nails
; ++i
){
70 vector
<Point
> chull
= convexHull(g
);
71 /*for (int i=0; i<chull.size(); i++){
72 printPnt(chull[i]); cout << " ";
75 if (chull
.size() > 1){
76 long double dlen
= (long double)ilen
;
77 long double dist
= 0.0;
78 for (int i
=0; i
<chull
.size()-1; i
++){
80 //cout << "dist "<<i<<" es: " << dist <<endl;
81 dist
+= (long double)sqrt((chull
[i
].x
-chull
[i
+1].x
)*(chull
[i
].x
-chull
[i
+1].x
)+(chull
[i
].y
-chull
[i
+1].y
)*(chull
[i
].y
-chull
[i
+1].y
));
83 //cout << "dist es: " << dist << endl;
85 cout
<< ilen
<< ".00000\n";
87 printf("%.5Lf\n", dist
);
90 }else{ //solo hay un clavo
91 cout
<< ilen
<< ".00000\n";